package com.garen.utils;

import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.*;
import java.io.File;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.commons.configuration2.XMLConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.garen.common.IEasyUITree;

public class CommonUtils {

	protected static Log log = LogFactory.getLog(CommonUtils.class);
	public static final String TOMCAT_HOME_NAME = "catalina.home";
	public static final String TOMCAT_GAREN_DEPLOY= "TOMCAT_GAREN_DEPLOY";//项目发布标志,区别开发环境还是生成环境
	
	private static char randomChar() {
		Random r = new Random();
		// String s = "ABCDEFGHJKLMNPRSTUVWXYZ0123456789";
		String s = "0123456789";
		return s.charAt(r.nextInt(s.length()));
	}
	
	public static String drawImg(ByteArrayOutputStream output) {
		String code = "";
		//log.debug("生成验证码1");
		for (int i = 0; i < 4; i++) {
			code += randomChar();
		}
		int width = 80;
		int height = 45;
		BufferedImage bi = new BufferedImage(width, height,
				BufferedImage.TYPE_3BYTE_BGR);
		Font font = new Font("Times New Roman", Font.PLAIN, 20);
		Graphics2D g = bi.createGraphics();
		g.setFont(font);
		Color color = new Color(66, 2, 82);
		g.setColor(color);
		g.setBackground(new Color(226, 226, 240));
		g.clearRect(0, 0, width, height);
		//log.debug("生成验证码2");
		FontRenderContext context = g.getFontRenderContext();
		//log.debug("生成验证码20");
		Rectangle2D bounds = font.getStringBounds(code, context);
		double x = (width - bounds.getWidth()) / 2;
		double y = (height - bounds.getHeight()) / 2;
		//log.debug("生成验证码21");
		double ascent = bounds.getY();
		double baseY = y - ascent;
		g.drawString(code, (int) x, (int) baseY);
		g.dispose();
		//log.debug("生成验证码3");
		try {
			ImageIO.write(bi, "jpg", output);
		} catch (IOException e) {
			e.printStackTrace();
		}
		//log.debug("生成验证码4");
		return code;
	}
	
	//xpath 规则读取xml文件内容
	static public String readXMLValue(String path,String rule){
		String xmlpath = CommonUtils.getRealPath(path);
		return readXMLValueEx(xmlpath,rule);
	}
	
	//xpath 规则读取xml文件内容
	static public void writeXMLValue(String path,String rule,String value){
		String xmlpath = CommonUtils.getRealPath(path);
		writeXMLValueEx(xmlpath,rule,value);
	}
		
	//xpath 规则读取xml文件内容
	static public String readXMLValueEx(String xmlpath,String rule){
		String value = null;
		Parameters params = new Parameters();
		FileBasedConfigurationBuilder<XMLConfiguration> builder =
				new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
				.configure(params.xml().setFileName(xmlpath));
		try{
		    XMLConfiguration config = builder.getConfiguration();
		    value = config.getString(rule);
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return value;
	}
		
	//xpath 规则读取xml文件内容
	static public void writeXMLValueEx(String xmlpath,String rule,String value){
		Parameters params = new Parameters();
		FileBasedConfigurationBuilder<XMLConfiguration> builder =
				new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
				.configure(params.xml().setFileName(xmlpath));
		try{
		    XMLConfiguration config = builder.getConfiguration();
		    config.setProperty(rule, value);
		    builder.save();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
		
	//获取tomcat根目录 + 相对地址
	static public String getRealPath(String path){
		if(path == null) path = "";
		return System.getProperty(TOMCAT_HOME_NAME) + path;
	}
	
	static public void printlog(String msg){
		log.debug(msg);
	}
	
	/*
	 * 字节数据匹配查找，返回-1 或 匹配问题索引
	 * */
	public static int binarySearch(byte[] source,int offset,byte[] dest){
		int ret = -1;
		if(source == null || dest == null) return ret;
		int destLen = dest.length;
		int len = source.length - destLen;
		if(len < offset) return ret;
		for(int i = offset;i <= len;i++){
			int ii = i,j = 0;
			for(;j < destLen;j++){
				if(source[ii++] == dest[j]) continue;
				else break;
			}
			if(j == destLen) return i;//匹配成功
		}
		return ret;
	}
	/*
	 * 设置树节点状态
	 * @param treelist1 需要设置的树节点集合
	 * @param treelist2 选择状态的树节点集合
	 * @return
	 */
	public static List<? extends IEasyUITree> 
		setNodeCheck(List<? extends IEasyUITree> treelist1,
					List<? extends IEasyUITree> treelist2){
		for(IEasyUITree m1 : treelist1){
			Integer id1 = m1.getId();
			if(id1 == null) continue;//主键无效，跳过
			for(IEasyUITree m2 : treelist2){
				Integer id2 = m2.getId();
				if(id1.equals(id2)){
					m1.setChecked(true);
					break;
				}
			}
		}
		return treelist1;
	}
    
	//树结构父节点相等比较

	static public boolean comparePid(Integer pid1,Integer pid2){
		if(pid1 == null) {
			if(pid2 == null) return true;
		}else {
			if(pid1.equals(pid2)) return true;
		}
		return false;
	}
	
	/*
	 * List结构，转换为树结构   !
	 * @param treelist 要转换的List，必须实现接口IEasyUITree
	 * @param pIdValue 判断根节点的值 ：  0 or null
	 */
	public static void list2Tree(List<? extends IEasyUITree> treelist){
		for(IEasyUITree m1 : treelist){
			Integer id1 = m1.getId();
			if(id1 == null) continue;
			List<IEasyUITree> children = m1.getChildren();
			for(IEasyUITree m2 : treelist){
				Integer pid = m2.getPid();
				//父节点为空或同一实例,继续下一个
				if(pid == null || m1 == m2)  continue;
				if(id1.equals(pid)){
					children.add(m2);
					m2.setFlag(true);
					m1.setChecked(false);//有子节点的默认false
				}
			}
		}
		Iterator<? extends IEasyUITree> it =  treelist.iterator();
		while(it.hasNext()){
			IEasyUITree dtdep = it.next();
			if(dtdep.getFlag())
				it.remove();//删除不是根节点
		}
	}
	
	 
/*
 * class资源遍历方法
 * */
	public static void findClass(File f,Set<String>  set,String prefix){
		for(File subfile : f.listFiles()){
			if(subfile.isDirectory()) 
				findClass(subfile,set,prefix);
			else{
				String className = subfile.getName();
				if(className.endsWith(".class") &&
						prefix.equals(subfile.getParentFile().getName()))
					set.add(subfile.getPath());
			}
		}
	}
	
	/*
	 * 异常内存转化为字符串
	 */
	public static String log4stack(Exception ex){
		String ret = null;
		if(ex == null) return null;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		PrintStream ps = new PrintStream(os);
		ex.printStackTrace(ps);
		ret = new String(os.toByteArray());
		return ret;
	}
		
	/*
	 * SHA方式加密字符串
	 * @param inputStr
	 * @return
	 */
	static public String encryptSHA(String inputStr) {   
        byte[] inputData = inputStr.getBytes();
        MessageDigest sha =  null;
		try {
			sha = MessageDigest.getInstance("SHA");
			sha.update(inputData);
	        byte[] d = sha.digest();
	        BigInteger bigSha = new BigInteger(d); 
	        return bigSha.toString(32);  
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
    }   
	
	/*
	 * 正则表达式匹配字符串 !
	 * @param content 源字符串
	 * @param regx 正则表达式
	 * @return 匹配的内容
	 */
	public static String regx(String content, String regx) {
		if (content == null || regx == null) return null;
		Pattern p = Pattern.compile(regx);
		Matcher m = p.matcher(content);
		if (m.find()) {
			//if (log.isDebugEnabled()) log.debug(m.groupCount() + "==" + m.group());
			if (m.groupCount() == 1) return m.group(1);
		}
		return null;
	}
	
	/*
	 * 正则表达式匹配字符串 !
	 * @param content 源字符串
	 * @param regx 正则表达式
	 * @return 匹配的内容
	 */
	public static boolean isMatches(String content, String regx) {
		if (content == null || regx == null) return false;
		Pattern p = Pattern.compile(regx,Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(content);
		return m.find();
	}
	
	
		
}
